﻿using System;
using System.Diagnostics;
using System.Text;


namespace AudioMonitor
{
    public class MulticastAudioConverter : IDisposable
    {
        private readonly AudioConverterInfo _converterInfo;

        private Process _ffmpegProcess;
        private StringBuilder _errorOutput;

        public MulticastAudioConverter(AudioConverterInfo converterInfo)
        {
            _converterInfo = converterInfo;
        }

        public bool StartConversion(out string errorMessage)
        {
            try
            {
                string ffmpegArgs =// $"-loglevel warning" +
                                    $" -i \"{_converterInfo.SourcePath}\" " +
                                    $"-map 0:#{_converterInfo.PID} " +
                                    $"-acodec pcm_s{_converterInfo.PlayInfo.BitsPerSample}le " +
                                    $"-ar {_converterInfo.PlayInfo.SampleRate} " +
                                    $"-ac {_converterInfo.PlayInfo.Channels} " +
                                    $"-f s{_converterInfo.PlayInfo.BitsPerSample}le \"{_converterInfo.PlayInfo.URL}\"";

                _errorOutput = new StringBuilder();
                _ffmpegProcess = new Process
                {
                    StartInfo = new ProcessStartInfo
                    {
                        FileName = "ffmpeg",
                        Arguments = ffmpegArgs,
                        UseShellExecute = true,
                        CreateNoWindow = false,
                        RedirectStandardError = false,
                        RedirectStandardOutput = false,
                        WindowStyle = ProcessWindowStyle.Minimized,
                    },
                    EnableRaisingEvents = true
                };

                _ffmpegProcess.ErrorDataReceived += (sender, e) =>
                {
                    if (!string.IsNullOrEmpty(e.Data))
                        _errorOutput.AppendLine(e.Data);
                };

                AppDomain.CurrentDomain.ProcessExit += (s, e) =>
                {
                    if (!_ffmpegProcess.HasExited)
                        _ffmpegProcess.Kill();
                };

                _ffmpegProcess.Start();
                //_ffmpegProcess.BeginErrorReadLine();

                //// 等待初始连接建立（3秒超时）
                //if (!_ffmpegProcess.WaitForExit(3000))
                //{
                //    errorMessage = "FFmpeg process started successfully";
                //    return true;
                //}

                //// 如果进程已退出，检查退出码
                //if (_ffmpegProcess.ExitCode != 0)
                //{
                //    errorMessage = $"FFmpeg failed with exit code {_ffmpegProcess.ExitCode}: {_errorOutput}";
                //    return false;
                //}

                //errorMessage = "FFmpeg process terminated unexpectedly";
                //return false;
                errorMessage = "?";
                return true;
            }
            catch (Exception ex)
            {
                errorMessage = $"Failed to start FFmpeg: {ex.Message}";
                return false;
            }
        }

        public bool CheckConversionStatus(out string statusMessage)
        {
            if (_ffmpegProcess == null)
            {
                statusMessage = "FFmpeg process not started";
                return false;
            }

            if (_ffmpegProcess.HasExited)
            {
                if (_ffmpegProcess.ExitCode == 0)
                {
                    statusMessage = "Conversion completed successfully";
                    return true;
                }

                statusMessage = $"Conversion failed (Exit code: {_ffmpegProcess.ExitCode}): {_errorOutput}";
                return false;
            }

            statusMessage = "Conversion in progress";
            return true;
        }

        public void StopConversion()
        {
            try
            {
                if (_ffmpegProcess != null && !_ffmpegProcess.HasExited)
                {
                    _ffmpegProcess.Kill();
                    _ffmpegProcess.WaitForExit(1000);
                }
            }
            finally
            {
                Dispose();
            }
        }

        public void Dispose()
        {
            _ffmpegProcess?.Dispose();
        }
    }

}
